package com.lulalei.dbviewer.service.impl;

import com.lulalei.dbviewer.commons.api.ResultBean;
import com.lulalei.dbviewer.commons.bean.GenerateBean;
import com.lulalei.dbviewer.commons.bean.JDBCConnectBean;
import com.lulalei.dbviewer.commons.bean.TableBean;
import com.lulalei.dbviewer.commons.cache.CacheManager;
import com.lulalei.dbviewer.commons.cache.CacheMap;
import com.lulalei.dbviewer.commons.exception.CustomizeException;
import com.lulalei.dbviewer.commons.factory.GenerateBeanFactory.GenerateBeanFactory;
import com.lulalei.dbviewer.commons.factory.GenerateBeanFactory.OtherModuleGenerateBeanFactory;
import com.lulalei.dbviewer.commons.factory.GenerateBeanFactory.OwnModuleGenerateBeanFactory;
import com.lulalei.dbviewer.commons.factory.GenerateCodeFactory.GenerateCodeFactory;
import com.lulalei.dbviewer.commons.utils.SpringUtils;
import com.lulalei.dbviewer.db.DBService;
import com.lulalei.dbviewer.dto.DBConnectDTO;
import com.lulalei.dbviewer.dto.DBTablesInfoDTO;
import com.lulalei.dbviewer.dto.GenerateDTO;
import com.lulalei.dbviewer.service.ViewerService;
import com.lulalei.dbviewer.strategy.DBStrategyManager;
import com.lulalei.dbviewer.vo.LinkedDBVO;
import com.lulalei.dbviewer.vo.PageVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class ViewerServiceImpl implements ViewerService {

    @Autowired
    private DBStrategyManager dbManager;

    @Autowired
    @Qualifier("velocityGenerateFactory")
    private GenerateCodeFactory generateCodeFactory;


    @Override
    public ResultBean<List<LinkedDBVO>> getLinkDBs() {
        CacheMap jdbc = CacheManager.getCacheMap("jdbc");

        List<LinkedDBVO> linkedDBVOS = new ArrayList<>();

        //不存在已经连接的返回空集合
        if (jdbc == null || jdbc.size() == 0) {
            return ResultBean.success(linkedDBVOS);
        }


        //解析成LinkedDBVO
        Map<String, Object> map = jdbc.getMap();
        for (Map.Entry<String, Object> stringObjectEntry : map.entrySet()) {
            JDBCConnectBean connectBean = (JDBCConnectBean) stringObjectEntry.getValue();

            LinkedDBVO linkedDBVO = new LinkedDBVO();
            linkedDBVO.setName(connectBean.getDbInfo().getName());
            linkedDBVO.setComment(connectBean.getDbInfo().getComment());

            linkedDBVOS.add(linkedDBVO);
        }
        return ResultBean.success(linkedDBVOS);
    }

    @Override
    public ResultBean<Boolean> connect(DBConnectDTO dbConnectDTO) throws CustomizeException, SQLException {
        //校验连接名是否存在
        CacheMap jdbc = CacheManager.getNotNullCacheMap("jdbc");
        Object res = jdbc.get(dbConnectDTO.getName());
        if (res != null) {
            throw new CustomizeException("连接名已存在");
        }

        DBService dbService = dbManager.getDBService(dbConnectDTO.getDbType().name());
        return ResultBean.success(dbService.connect(dbConnectDTO));
    }

    @Override
    public ResultBean<PageVO<TableBean>> getTablesInfo(DBTablesInfoDTO dbTablesInfoDTO) throws CustomizeException, SQLException {
        //获取对应的连接
        CacheMap jdbc = CacheManager.getCacheMap("jdbc");
        JDBCConnectBean jdbcConnectBean = (JDBCConnectBean) jdbc.get(dbTablesInfoDTO.getConnectionName());
        //根据连接的类型进行不同的操作
        DBService dbService = dbManager.getDBService(jdbcConnectBean.getDbInfo().getDbType().name());
        return ResultBean.success(dbService.getTableInfo(dbTablesInfoDTO));
    }

    @Override
    public ResultBean<String> generate(GenerateDTO generateDTO) throws CustomizeException {
        //数据准备
        String moduleName = generateDTO.getModuleName();
        GenerateBeanFactory factory;
        if (moduleName == null || moduleName.equals("")) {
            factory = SpringUtils.getBean(OwnModuleGenerateBeanFactory.class);
        } else {
            factory = SpringUtils.getBean(OtherModuleGenerateBeanFactory.class);
        }
        GenerateBean generateBean = factory.createGenerateBean(generateDTO);

        //生成代码
        generateCodeFactory.generateAll(generateBean);

        return ResultBean.success();
    }

}
